﻿using System;
using System.Collections.Generic;
using CI.Interfaces;

namespace CI.Organism
{
    /// <summary>Collection class of all organisms, alive, dead, inactive</summary>
    public interface IOrganismCollection : IEnumerable<IOrganism>
    {
        /// <summary>Sub collection of the alive organisms</summary>
        SynchronizedCollection<IOrganism> Alive { get; set; }

        /// <summary>Sub Collection of Dead Organisms</summary>
        SynchronizedCollection<IOrganism> Dead { get; set; }

        /// <summary>Sub collection of inactive organisms, they are dead and not not on the screen</summary>
        SynchronizedCollection<IOrganism> Inactive { get; set; }

        /// <summary>Hosting Environment the organisms belong to</summary>
        IHostingEnvironment hostEnvironment { get; set; }

        /// <summary>Sub colleciton of all the organisms which have the dirty location flagged mark and need updating</summary>
        IList<IOrganism> DirtyLocations { get; set; }

        event Action<IOrganism> OnAliveAddEvent;
        event Action<IOrganism> OnAliveRemoveEvent;
        event Action<IOrganism> OnDeadAddEvent;
        event Action<IOrganism> OnDeadRemoveEvent;
        event Action<IOrganism> OnInactiveAddEvent;
        event Action<IOrganism> OnInactiveRemoveEvent;

        void AliveAdd(IOrganism organism);
        void AliveRemove(IOrganism organism);
        void DeadAdd(IOrganism organism);
        void DeadRemove(IOrganism organism);
        void InactiveAdd(IOrganism organism);
        void InactiveRemove(IOrganism organism);

        /// <summary>
        /// creates a new list based on the organisms if they have the dirty flag set and clears the organisms dirty flag
        /// Note : if its already been done this heartbeat it wont happen again.
        /// </summary>
        void DirtyLocationsRebuild();

        /// <summary>
        /// Find the Organism with the specifed guid
        /// </summary>
        /// <param name="guid">guid to find</param>
        /// <returns>Cell</returns>
        IOrganism Find(Guid guid);

        /// <summary>
        /// see if the organism collection contains the organism
        /// </summary>
        /// <param name="organism"></param>
        /// <returns></returns>
        bool Contains(IOrganism organism);

        /// <summary>
        /// ToString with a fitness function
        /// </summary>
        /// <returns></returns>
        string ToString(IFitnessFunction fitnessFunction);
    }
}